package com.gongzhiyun.springboot3test.interceptor;

import com.gongzhiyun.springboot3test.entity.user.AuthInfo;
import com.gongzhiyun.springboot3test.service.RedisService;
import com.gongzhiyun.springboot3test.utils.IpUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
@Slf4j
@RequiredArgsConstructor
public class AppInterceptor implements HandlerInterceptor {
    private final RedisService redisService;
    private static final ThreadLocal<AuthInfo> threadLocal = new ThreadLocal<>();

    public static AuthInfo get() {
        return threadLocal.get();
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("拦截的api====={}", request.getRequestURI());
        //验证是否是控制器
        if (handler instanceof HandlerMethod hm) {

            // 创建认证信息并放置到线程现场
            AuthInfo authInfo = new AuthInfo();
            threadLocal.set(authInfo);
            // 获取请求头中的token信息
            String token = request.getHeader("Authorization");
            token = token == null ? "" : token;
            authInfo.setToken(token);
            authInfo.setIp(IpUtils.getIpAddress());
            // 请求的相关信息
            authInfo.setUrl(request.getRequestURI());
            authInfo.setMethod(request.getMethod());
            // 获取控制器的mapping信息
            Class<?> clazz = hm.getBeanType();
            RequestMapping rm = clazz.getAnnotation(RequestMapping.class);
            String mapping = rm == null || rm.value().length == 0 ? "" : rm.value()[0];
            rm = hm.getMethodAnnotation(RequestMapping.class);
            mapping += rm == null || rm.value().length == 0 ? "" : rm.value()[0];
            authInfo.setMapping(mapping);
            //获取登录的用户id
            if (redisService.has(authInfo.getToken())) {
                authInfo.setUid(redisService.get(authInfo.getToken(), Integer.class));
            }
            log.debug("认证的相关信息;{}", authInfo);
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.debug("拦截完毕");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.debug("拦截后置");
    }
}
